/*!
 * WADE JavaScript Library v2.0 for zepto
 * http://www.wadecn.com/
 * auth:xiedx@asiainfo-linkage.com
 * Copyright 2014, WADE
 * 需要配合jquery使用
 */
	var rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
	push=Array.prototype.push;
	var Wade={};
	/**
	* 数据总线相关
	**/	 
	var escapeRe=function (d){
		return d.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
	};
	var support = {
		scriptEval: false
	};
	var toString = Object.prototype.toString;

	Wade.Collection = function(allowFunctions, keyFn){
	    this.items = [];
	    this.map = {};
	    this.keys = [];
	    this.length = 0; 
	    this.allowFunctions = allowFunctions === true;
	    if(keyFn){
	        this.getKey = keyFn;
	    }
	};
	
	Wade.Collection.prototype={
	    allowFunctions : false,
	    add : function(key, o){
	        if(arguments.length == 1){
	            o = arguments[0];
	            key = this.getKey(o);
	        }
	        if(typeof key != 'undefined' && key !== null){
	            var old = this.map[key];
	            if(typeof old != 'undefined'){
	                return this.replace(key, o);
	            }
	            this.map[key] = o;
	        }
	        this.length++;
	        this.items.push(o);
	        this.keys.push(key);
	        return o;
	    },
	    getKey : function(o){
	         return o.id;
	    },
	    replace : function(key, o){
	        if(arguments.length == 1){
	            o = arguments[0];
	            key = this.getKey(o);
	        }
	        var old = this.map[key];
	        if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
	             return this.add(key, o);
	        }
	        var index = this.indexOfKey(key);
	        this.items[index] = o;
	        this.map[key] = o;
	        return o;
	    },
	    addAll : function(objs){
	        if(arguments.length > 1 || $.isArray(objs)){
	            var args = arguments.length > 1 ? arguments : objs;
	            for(var i = 0, len = args.length; i < len; i++){
	                this.add(args[i]);
	            }
	        }else{
	            for(var key in objs){
	                if(this.allowFunctions || typeof objs[key] != 'function'){
	                    this.add(key, objs[key]);
	                }
	            }
	        }
	    },
	    //增加map的putAll方法
	    putAll:function(objs){
	    	var _this=this;
	    	if(objs&&typeof objs!='undefined'&&typeof objs.keys!='undefined'&&typeof objs.items!='undefined'){
	    		$.each(objs.keys,function(index,key){
	    			_this.put(key,objs.get(key));
	    		});
	    		return;
	    	}
	    	_this.addAll(objs);
	    	
	    },
	    each : function(fn, scope){
	        var items = [].concat(this.items); // each safe for removal
	        for(var i = 0, len = items.length; i < len; i++){
	            if(fn.call(scope || items[i], items[i], i, len) === false){
	                break;
	            }
	        }
	    },
	    eachKey : function(fn, scope){
	        for(var i = 0, len = this.keys.length; i < len; i++){
	            fn.call(scope || window, this.keys[i], this.items[i], i, len);
	        }
	    },
	    find : function(fn, scope){
	        for(var i = 0, len = this.items.length; i < len; i++){
	            if(fn.call(scope || window, this.items[i], this.keys[i])){
	                return this.items[i];
	            }
	        }
	        return null;
	    },
	    insert : function(index, key, o){
	        if(arguments.length == 2){
	            o = arguments[1];
	            key = this.getKey(o);
	        }
	        if(this.containsKey(key)){
	            this.suspendEvents();
	            this.removeKey(key);
	            this.resumeEvents();
	        }
	        if(index >= this.length){
	            return this.add(key, o);
	        }
	        this.length++;
	        this.items.splice(index, 0, o);
	        if(typeof key != 'undefined' && key !== null){
	            this.map[key] = o;
	        }
	        this.keys.splice(index, 0, key);
	        return o;
	    },
	    remove : function(o){
	        return this.removeAt(this.indexOf(o));
	    },
	    removeAt : function(index){
	        if(index < this.length && index >= 0){
	            this.length--;
	            var o = this.items[index];
	            this.items.splice(index, 1);
	            var key = this.keys[index];
	            if(typeof key != 'undefined'){
	                delete this.map[key];
	            }
	            this.keys.splice(index, 1);
	            return o;
	        }
	        return false;
	    },
	    removeKey : function(key){
	        return this.removeAt(this.indexOfKey(key));
	    },
	    getCount : function(){
	        return this.length;
	    },
	    indexOf : function(o){
	        return $.inArray(o,this.items);
	    },
	    indexOfKey : function(key){
	        return $.inArray(key,this.keys);
	    },
	    item : function(key){
	        var mk = this.map[key],
	            item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
	        return typeof item != 'function' || this.allowFunctions ? item : null; // for prototype!
	    },
	    itemAt : function(index){
	        return this.items[index];
	    },
	    key : function(key){
	        return this.map[key];
	    },
	    contains : function(o){
	        return this.indexOf(o) != -1;
	    },
	    containsKey : function(key){
	        return typeof this.map[key] != 'undefined';
	    },
	    clear : function(){
	        this.length = 0;
	        this.items = [];
	        this.keys = [];
	        this.map = {};
	    },
	    first : function(){
	        return this.items[0];
	    },
	    last : function(){
	        return this.items[this.length-1];
	    },
	    _sort : function(property, dir, fn){
	        var i, len,
	            dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
	
	            //this is a temporary array used to apply the sorting function
	            c     = [],
	            keys  = this.keys,
	            items = this.items;
	
	        //default to a simple sorter function if one is not provided
	        fn = fn || function(a, b) {
	            return a - b;
	        };
	
	        //copy all the items into a temporary array, which we will sort
	        for(i = 0, len = items.length; i < len; i++){
	            c[c.length] = {
	                key  : keys[i],
	                value: items[i],
	                index: i
	            };
	        }
	
	        //sort the temporary array
	        c.sort(function(a, b){
	            var v = fn(a[property], b[property]) * dsc;
	            if(v === 0){
	                v = (a.index < b.index ? -1 : 1);
	            }
	            return v;
	        });
	
	        //copy the temporary array back into the main this.items and this.keys objects
	        for(i = 0, len = c.length; i < len; i++){
	            items[i] = c[i].value;
	            keys[i]  = c[i].key;
	        }
	    },
	    sort : function(dir, fn){
	        this._sort('value', dir, fn);
	    },
	    reorder: function(mapping) {
	        this.suspendEvents();
	
	        var items     = this.items,
	            index     = 0,
	            length    = items.length,
	            order     = [],
	            remaining = [];
	
	        //object of {oldPosition: newPosition} reversed to {newPosition: oldPosition}
	        for (oldIndex in mapping) {
	            order[mapping[oldIndex]] = items[oldIndex];
	        }
	
	        for (index = 0; index < length; index++) {
	            if (mapping[index] == undefined) {
	                remaining.push(items[index]);
	            }
	        }
	
	        for (index = 0; index < length; index++) {
	            if (order[index] == undefined) {
	                order[index] = remaining.shift();
	            }
	        }
	
	        this.clear();
	        this.addAll(order);
	
	        this.resumeEvents();
	    },
	    keySort : function(dir, fn){
	        this._sort('key', dir, fn || function(a, b){
	            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
	            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
	        });
	    },
	    getRange : function(start, end){
	        var items = this.items;
	        if(items.length < 1){
	            return [];
	        }
	        start = start || 0;
	        end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
	        var i, r = [];
	        if(start <= end){
	            for(i = start; i <= end; i++) {
	                r[r.length] = items[i];
	            }
	        }else{
	            for(i = start; i >= end; i--) {
	                r[r.length] = items[i];
	            }
	        }
	        return r;
	    },
	    filter : function(property, value, anyMatch, caseSensitive){
	        if(!value){
	            return this.clone();
	        }
	        value = this.createValueMatcher(value, anyMatch, caseSensitive);
	        return this.filterBy(function(o){
	            return o && value.test(o[property]);
	        });
	    },
	    filterBy : function(fn, scope){
	        var r = new Wade.Collection();
	        r.getKey = this.getKey;
	        var k = this.keys, it = this.items;
	        for(var i = 0, len = it.length; i < len; i++){
	            if(fn.call(scope||this, it[i], k[i])){
	                r.add(k[i], it[i]);
	            }
	        }
	        return r;
	    },
	    findIndex : function(property, value, start, anyMatch, caseSensitive){
	        if(!value){
	            return -1;
	        }
	        value = this.createValueMatcher(value, anyMatch, caseSensitive);
	        return this.findIndexBy(function(o){
	            return o && value.test(o[property]);
	        }, null, start);
	    },
	    findIndexBy : function(fn, scope, start){
	        var k = this.keys, it = this.items;
	        for(var i = (start||0), len = it.length; i < len; i++){
	            if(fn.call(scope||this, it[i], k[i])){
	                return i;
	            }
	        }
	        return -1;
	    },
	    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
	        if (!value.exec) { // not a regex
	            value = String(value);
	
	            if (anyMatch === true) {
	                value = escapeRe(value);
	            } else {
	                value = '^' + escapeRe(value);
	                if (exactMatch === true) {
	                    value += '$';
	                }
	            }
	            value = new RegExp(value, caseSensitive ? '' : 'i');
	         }
	         return value;
	    },
	    clone : function(){
	        var r = new Wade.Collection();
	        var k = this.keys, it = this.items;
	        for(var i = 0, len = it.length; i < len; i++){
	            r.add(k[i], it[i]);
	        }
	        r.getKey = this.getKey;
	        return r;
	    }
	};
	
	/*
	* 扩展常用方法
	* isArray|isPlainObject|isEmptyObject,三个方法zepto已经存在
	*/
	$.extend($,{
		error:function( msg ) {
			throw msg;
		},
		isNumber:function(value) {
            return typeof value === 'number' && isFinite(value);
        },
        isNumeric: function(value) {
            return !isNaN(parseFloat(value)) && isFinite(value);
        },
        isString: function(value) {
            return typeof value === 'string';
        },
        isBoolean: function(value) {
            return typeof value === 'boolean';
        },
		isFunction:function(obj){
			return toString.call(obj) === "[object Function]";
		},
		/*isArray:function(obj) {
			return toString.call(obj) === "[object Array]";
		},*/
		//判断是否为object类型的对象
		isObject:function(obj){
			return toString.call(obj) === "[object Object]";
		},
		isEmptyObject:function(obj){
			for (var name in obj) {
				return false;
			}
			return true;
		},
        isElement: function(value) {
            return value ? value.nodeType !== undefined : false;
        },
        isNodeName:function(elem,name){
        	return $.nodeName(elem,name);
        },		
		//判定nodeName
		nodeName:function(elem, name){
			return elem.nodeName && elem.nodeName.toUpperCase()=== name.toUpperCase();
		},
		isWindow: function( obj ) {
			return obj && typeof obj === "object" && "setInterval" in obj;
		},
		trim: function(text) {
			return (text || "").replace(rtrim,"");
		},
		//判断item是否在数组array中
		inArray: function(item, array){
			if(array.indexOf){
				return array.indexOf(item);
			}
			//遍历array进行判定
			for(var i=0,length=array.length;i<length;i++){
				if(array[i]===item){
					return i;
				}
			}
			return -1;
		},
		makeArray:function(array, results){
			var ret = results || [];
			if ( array != null ) {
				//如果arry不是数组类型,则直接将array push到ret中
				if(array.length == null || typeof array === "string" || $.isFunction(array) || (typeof array !== "function" && array.setInterval)){
					push.call(ret, array);
				}else{
					$.merge(ret, array);
				}
			}
			return ret;
		},
		//复制数组对象
		merge:function(first, second) {
			var i = first.length, j = 0;
			if(typeof second.length === "number"){
				for(var l = second.length; j<l; j++) {
					first[i++]=second[j];
				}
			}else{
				while(second[j]!==undefined){
					first[i++]=second[j++];
				}
			}
			first.length = i;
			return first;
		},
		grep: function( elems, callback, inv ) {
			var ret = [];
			//遍历元素数组，在每个元素上执行callback，并返回执行结果有返回值不为false的结果集
			for ( var i = 0, length = elems.length; i < length; i++ ) {
				if ( !inv !== !callback( elems[ i ], i ) ) {
					ret.push( elems[ i ] );
				}
			}
			return ret;
		}, 
		map: function( elems, callback, arg) {
			var ret = [], value;
	
			//遍历元素数组， 在每个元素上执行callback，并返回所有的执行结果
			for ( var i = 0, length = elems.length; i < length; i++ ) {
				value = callback( elems[ i ], i, arg );
	
				if ( value != null ) {
					ret[ ret.length ] = value;
				}
			}
			return ret.concat.apply( [], ret );
		},		
		each:function( object, callback, args ) {
			var name, i = 0,
				length = object.length,
				isObj = length === undefined || $.isFunction(object);

			if (args){
				if (isObj) {
					for (name in object){
						if (callback.apply(object[name], args)===false){
							break;
						}
					}
				}else{
					for(;i<length;){
						if(callback.apply(object[i++],args)===false){
							break;
						}
					}
				}
			}else{
				if(isObj){
					for(name in object){
						if (callback.call(object[name],name,object[name])===false){
							break;
						}
					}
				}else{
					for(var value=object[0];
						i<length && callback.call(value,i,value)!==false;value=object[++i]){}
				}
			}
			return object;
		},
		parseJSON: function( data ) {
			if ( typeof data !== "string" || !data ) {
				return null;
			}
			//去除首尾空格
			data = $.trim(data);
			//使用正则表达式确保传入的字符串是json
			if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
				.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
				.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
						
				//console.log("########data");
				//先尝试使用浏览器内部JSON解析器
				return window.JSON && window.JSON.parse ?
					window.JSON.parse( data ) :
					(new Function("return " + data))();
			} else {
				$.error( "Invalid JSON: " + data );
			}
		},
		//UserAgent检测
		uaMatch: function(ua) {
			ua = ua.toLowerCase();
			var match = /(webkit)[ \/]([\w.]+)/.exec(ua) ||
				/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
				/(msie) ([\w.]+)/.exec(ua) ||
				!/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) ||
				/(gecko)[ \/]([^\s]*)/i.exec(ua) || 
				[];

			return {browser: match[1] || "", version: match[2] || "0" };
		},	
		browser: {}
	});

	$.extend($,{
		parseJsonString:function(str){ //过滤Json串中特殊字符以构造Json
			if(!str || !typeof(str)=="string"){return "";}
			
			str=str.replace(/([:{}\[\]\"])[\s|\u00A0]+/g,"$1"); //替换 :{}[]" 符号的右侧空格
			str=str.replace(/[\s|\u00A0]+([:{}\[\]\"])/g,"$1"); //替换 :{}[]" 符号的左侧空格

			//str=str.replace(/,([^\":{}\[\]]+):([\"{\[]{1})/g,",\"$1\":$2");   //把JSON串中无引号的键名加上双引号(1:处理,xxx:("|{|[))
			//str=str.replace(/\{([^\":{}\[\]]+):([\"{\[]{1})/g,"{\"$1\":$2");  //把JSON串中无引号的键名加上双引号(2:处理{xxx:("|{|[))
		   
			str=str.replace(/,([^\":{}\[\]]+):\"/g,",\"$1\":\"");  //把JSON串中无引号的键名加上双引号(1:处理 ,xxx:")
			str=str.replace(/,([^\":{}\[\]]+):\{/g,",\"$1\":{");   //把JSON串中无引号的键名加上双引号(1:处理 ,xxx:{)
			str=str.replace(/,([^\":{}\[\]]+):\[/g,",\"$1\":[");   //把JSON串中无引号的键名加上双引号(1:处理 ,xxx:[)
		
			str=str.replace(/\{([^\":{}\[\]]+):\"/g,"{\"$1\":\""); //把JSON串中无引号的键名加上双引号(1:处理 {xxx:")
			str=str.replace(/\{([^\":{}\[\]]+):\{/g,"{\"$1\":{");  //把JSON串中无引号的键名加上双引号(1:处理 {xxx:{)
			str=str.replace(/\{([^\":{}\[\]]+):\[/g,"{\"$1\":[");  //把JSON串中无引号的键名加上双引号(1:处理 {xxx:[)
		
			str=str.replace(/\\\":(null|undefined)(,|})/g,"\\\":\\\"\\\"$2"); //处理KEY值里放IData或IDataset的toString串里的空值
			str=str.replace(/\\\":(true|false)(,|})/g,"\\\":\\\"$1\\\"$2"); //处理KEY值里放IData或IDataset的toString串里的布尔值
			str=str.replace(/\\\":(-)?([0-9\.]+)(,|})/g,"\\\":\\\"$1$2\\\"$3"); //处理KEY值里放IData或IDataset的toString串里的数值
			//ybf326
			//str=str.replace(/\\\"/g,"!~b~!"); //把字符串中原有的 \" 替换，处理KEY值里放IData或IDataset的toString串的情况
			
			str=str.replace(/:(null|undefined)(,|})/g,":\"\"$2");    //将null或undefined替换为空字符
			str=str.replace(/:(true|false)(,|})/g,":\"$1\"$2");      //将true|false替换为字符串
			str=str.replace(/:(-)?([0-9\.]+)(,|})/g,":\"$1$2\"$3");  //将数字替换为字符串
			
			//str=str.replace(datafilter,"");    //过滤允许字符之外的字符
			//str=str.replace(datareplacer,"$1:$3"); //处理bude串的=号替换为:号
			
			/*
			str=str.replace(/\r|\t|\n|\"/g,function(m){
					switch(m){
						case "\r":m="\u005Cr";break;
						case "\t":m="\u005Ct";break;
						case "\n":m="\u005Cn";break;
						case "\"":m="!~a~!";break;
					}return m;});  //处理回车换行制表符
			*/
			var out = "";
			for(var i=0;i<str.length;i++){
				var chr = str.charAt(i);
				switch (chr){
					case "\b":
						out +="\u005Cb";
						break;
					case "\f":
						out +="\u005Cf";
						break;
					case "\r":
						out +="\u005Cr";
						break;
					case "\t":
						out +="\u005Ct";
						break;
					case "\n":
						out +="\u005Cn";
						break;
					//ybf326
					/*case "\"":
						out +="!~a~!";
						break;*/
					default:
						out += chr;
					break;
				}
			}
			str = out;
		
			//ybf326
			/*
			//第一次替换处理JSON格式的双引号字符
			str=str.replace(/{!~a~!/g,"{\""); //处理 {"
			str=str.replace(/!~a~!}/g,"\"}");  //处理 "}
			str=str.replace(/!~a~!,!~a~!/g,"\",\"");   //处理 ","
			str=str.replace(/!~a~!:!~a~!/g,"\":\"");   //处理 ":"
			str=str.replace(/!~a~!:\[/g,"\":[");   //处理 ":[
			str=str.replace(/\],!~a~!/g,"],\"");   //处理 ],"
			str=str.replace(/!~a~!:{/g,"\":{");    //处理 ":{
			str=str.replace(/},!~a~!/g,"},\"");    //处理 },"
		
			//第二次替换处理其它的双引号
			str=str.replace(/\u005C!~a~!/g,"\u005C\""); //本身就有\的还原
			str=str.replace(/!~a~!/g,"\u005C\"");    //其它的加上\符号
			str=str.replace(/!~b~!/g,"\u005C\"");   //恢复 !~b~! 为 \"
			*/
			
			//str=str.replace(/\r/g,"\u005Cr");		
			//str=str.replace(/\n/g,"\u005Cn");	
			//str=str.replace(/([^,:\{\[])(\")([^,:\}\]])/g,"$1\u005C$2$3"); //处理json串值中的双引号
			//str=str.replace(/([^,\\:\{\[])(\")([^,\\:\}\]])/g,"$1\u005C$2$3"); //处理json串值中的双引号(两个双引号连一起的特殊情况)
			//str=str.replace(/\"(\")([^,:\}\]])/g,"\"\u005C$1$2"); //xiedx 2010-7-14 //处理json串值中的双引号(多个双引号连一起的特殊情况)
			//str=str.replace(/\"\,([^\"{\[])/g,"\u005C\"\,$1");   //处理字符串json值中有双引号和逗号在一起的情况(",)
			//str=str.replace(/([^\"}:\]])\,\"/g,"$1\,\u005C\"");  //处理字符串json值中有双引号和逗号在一起的情况(,")
			//str=str.replace(/\":\u005C\",/g,"\":\",");	//处理与值结束引号连在一起的双引号
			//str=str.replace(/,\u005C\"([\}\]]|(,\"))/g,",\"$1"); //处理与值结束引号连在一起的双引号
			return str;
		},
		parseJsonValue:function(str){ //替换json对象值中的特殊字符
			if(!str || !typeof(str)=="string"){return str;}
		
			var out = "";
			for(var i=0;i<str.length;i++){
				var chr = str.charAt(i);
				switch (chr){
					case "\b":
						out +="\u005Cb";
						break;
					case "\f":
						out +="\u005Cf";
						break;
					case "\r":
						out +="\u005Cr";
						break;
					case "\t":
						out +="\u005Ct";
						break;
					case "\n":
						out +="\u005Cn";
						break;
					case "\"":
						out +='\u005C"';
						break;
					//ybf326
					case "\\":
						out += "\u005C\u005C";
						break;
					default:
						out += chr;
					break;
				}
			}
			return out;
		}
	});	
	
	Wade.DataMap=function(data){
		//支持不使用new来构造
		if(!this.parseString) {
			return new Wade.DataMap(data);
		}
		Wade.Collection.call(this);	
		if(data){
			if($.isString(data)){
				this.parseString(data);
			}else if(typeof(data)=="object"){
				this.parseObject(data);
			}
		}
	};
	Wade.DataMap.prototype=new Wade.Collection();
	$.extend(Wade.DataMap.prototype,{
		get:function(key,defaultValue){
			var r=this.item(key);
			if(arguments.length>1 && (typeof(r)=="undefined" || r==null))
				return arguments[1];
			return r;
		},
		parseString:function(str){
			str=$.parseJsonString(str);
			//console.log("#####this.parseObject");
			return window.JSON && window.JSON.parse ? this.parseObject(window.JSON.parse(str)) 
					: (new Function("this.parseObject(" +str+")")).apply(this);
			//if(typeof(o)=="object")this.parseObject(o);
		},
		parseObject:function(obj){
			for(var p in obj){
				if(obj[p] && $.isArray(obj[p])){
					this.add(p,new Wade.DatasetList(obj[p]));
				}else if(obj[p] && $.isObject(obj[p])){
					this.add(p,new Wade.DataMap(obj[p]));
				}else{
					this.add(p,(obj[p]==undefined || obj[p]==null)?"":obj[p]);
				} 
			}
		}
	});

	Wade.DataMap.prototype.toString=function(){
			var cl=[],is="";
			for(var key in this.map){
				is="\"" + key + "\":";
				if(typeof(this.map[key])=="undefined" || this.map[key]==null){
					is+="\"\"";
				}else if(typeof(this.map[key])=="string" || !isNaN(this.map[key])){
					is+="\"" + $.parseJsonValue("" + this.map[key]) + "\"";
				}else{
					is+=this.map[key].toString();
				}
				cl.push(is);
			}
			return "{" + cl.join(",") + "}";
	};
	Wade.DataMap.prototype.put=Wade.DataMap.prototype.add;

	Wade.DatasetList=function(o){
		//支持不使用new来构造
		if(!this.parseString) {
			return new Wade.DatasetList(o);
		}
		this.items = [];
		this.length=0;
		if(typeof(o)=="string" && o!="")this.parseString(o);
		if(typeof(o)=="object" && (o instanceof Array) && o.length)this.parseArray(o);
	};
	$.extend(Wade.DatasetList.prototype,{
		add:function(o){
			this.length=(this.length+1);
			this.items.push(o);
		},
		item:function(index,key,defaultValue){
			if(index < this.length && index >= 0){
				var r= this.items[index];
				if((typeof(r)!="undefined") && (r instanceof Wade.DataMap) 
				&& arguments.length>1 && typeof(arguments[1])=="string" 
				&& arguments[1]!="" ){return r.get(key,defaultValue);}
				return r;
			}return;
		},	
		each:function(fn, scope){
			var items = [].concat(this.items); 
			for(var i = 0, len = items.length; i < len; i=i+1){
				if(fn.call(scope || items[i], items[i], i, len) === false){
					break;
				}
			}
		},   
		remove:function(o){
			return this.removeAt(this.indexOf(o));
		},	
		removeAt:function(index){
			if(index < this.length && index >= 0){
				this.length=(this.length-1);
				this.items.splice(index, 1);
			}		
		},
		indexOf:function(o){
			if(!this.items.indexOf){
				for(var i = 0, len = this.items.length; i < len; i=i+1){
					if(this.items[i] == o){ return i;}
				}
				return -1;
			}else{
				return this.items.indexOf(o);
			}
		},	
		getCount:function(){
			return this.length; 
		},	
		parseString:function(str){
			str=$.parseJsonString(str);
			//console.log("#####this.parseArray");
			return window.JSON && window.JSON.parse ? this.parseArray(window.JSON.parse(str)) : 
				(new Function("this.parseArray(" +str+")")).apply(this);	
		},
		parseArray:function(o){
			for(var i=0;i<o.length;i++){
				if(o[i] && $.isArray(o[i])){
					this.add(new Wade.DatasetList(o[i]));
				}else if(o[i] && $.isObject(o[i])){
					this.add(new Wade.DataMap(o[i]));
				}else{
					if(o[i]!=undefined && o[i]!=null)this.add(o[i]);
				} 
			}
		},
		clear:function(){
			this.items =[];
			this.length=0;
			//System.CG();
		}
	});
	Wade.DatasetList.prototype.toString=function(){
		var cl=[],is="";
		for(var i=0;i<this.items.length;i++){
			is="";
			if(typeof(this.items[i])=="undefined" || this.items[i]==null){
				is+="\"\"";
			}else if(typeof(this.items[i])=="string"){
				is="\"" + $.parseJsonValue(this.items[i]) + "\"";
			}else{
				is=this.items[i].toString();
			}
			cl.push(is);
		}
		return "[" + cl.join(",") + "]";
	};
	Wade.DatasetList.prototype.get=Wade.DatasetList.prototype.item;
	Wade.DatasetList.prototype.put=Wade.DatasetList.prototype.add;



